package com.qing.apple.filter.demo02;

import com.qing.apple.filter.bean.Apple;
import com.qing.apple.filter.bean.InitApple;
import com.qing.apple.filter.demo02.formatter.AppleFancyFormatter;
import com.qing.apple.filter.demo02.formatter.AppleSimpleFormatter;
import com.qing.apple.filter.demo02.predicate.AppleGreenColorPredicate;
import com.qing.apple.filter.demo02.predicate.AppleHeavyWeightPredicate;
import com.qing.apple.filter.demo02.predicate.ApplePredicate;
import com.qing.apple.filter.demo02.service.AppleService;

import java.util.Comparator;
import java.util.List;

public class Demo {
	public static void main(String[] args) {
		/**
		 * 行为参数化
		 */
		//筛选出红色的苹果
		List<Apple> greenApples= AppleService.filterApples( InitApple.getApples(),new AppleGreenColorPredicate());
		//筛选符合重量的苹果
		List<Apple> heavyWeightApples= AppleService.filterApples( InitApple.getApples(),new AppleHeavyWeightPredicate());

		/**
		 * TODO 行为参数化
		 * 优点：
		 * 1. 代码解耦
		 * 2. 当需求改变，新增筛选条件即可，即新增新的行为
		 * 缺点：
		 * 1.需要声明很多只要实例化一次的类
		 * 2. 当要把新的行为传递给filterApples方法的时候，你不得不声明好几个实现ApplePredicate接口的类，然后实例化好几个只会提到一次的ApplePredicate对象
		 */

		AppleService.prettyPrintApple(InitApple.getApples(),new AppleSimpleFormatter());

		System.out.println("-----------------------------------------");

		AppleService.prettyPrintApple(InitApple.getApples(),new AppleFancyFormatter());

		/**
		 * TODO 能不能做得更好呢？
		 * Java有一个机制称为匿名类，它可以让你同时声明和实例化一个类。它可以帮助你进一步改善代码，
		 * 让它变得更简洁。但这也不完全令人满意。
		 */
		List<Apple> redApples= AppleService.filterApples(InitApple.getApples(), new ApplePredicate() {
			@Override
			public boolean test(Apple apple) {
				return "red".equalsIgnoreCase(apple.getColor());
			}
		});

		/**
		 * TODO 匿名类缺点
		 * 第一，它往往很笨重，因为它占用了很多空间。
		 * 第二，很多程序员觉得它用起来很让人费解。
		 *
		 * 好的代码应该是一目了然的
		 */


		/**
		 * 使用在Java 8里可以用Lambda表达式重写
		 */
		List<Apple> redApples2= AppleService.filterApples(InitApple.getApples(), (apple)-> "red".equalsIgnoreCase(apple.getColor()));


		//List类型抽象化，可以直接作为工具使用
		List<Apple> appleList=AppleService.filter(InitApple.getApples(),apple -> apple.getWeight()>200);



	}
}
